package com.simple.util.security;

import com.simple.util.base.ByteUtil;
import com.simple.util.base.StringUtil;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

/**
 * @program: simple_tools
 * @description: DES加密
 * @author: Mr.chen
 * @create: 2020-06-08 16:04
 **/
public class DESedeEncrypt {

    private static String Algorithm = "DES";
    private static String Algorithm_mode = "DES/ECB/NOPADDING";

    static {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
    }

    /**
     * 加密
     *
     * @param input
     * @param keyStr
     * @return
     * @throws Exception
     */
    public static String encrypt(String input, String keyStr) throws Exception {
        byte[] inputBytes = StringUtil.fillStr(input, 8).getBytes();
        byte[] keyBytes = ByteUtil.fromHexString(keyStr);
        Cipher cipher = Cipher.getInstance(Algorithm_mode); // TripleDES/ECB/NoPadding
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] code = cipher.doFinal(inputBytes);
        return ByteUtil.byteArrayToHexString(code);
    }

    /**
     * 加密
     *
     * @param input
     * @param keyBytes
     * @return
     * @throws Exception
     */
    public static String encrypt(String input, byte[] keyBytes) throws Exception {
        byte[] inputBytes = StringUtil.fillStr(input, 8).getBytes();
        Cipher cipher = Cipher.getInstance(Algorithm_mode); // TripleDES/ECB/NoPadding
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] code = cipher.doFinal(inputBytes);
        return ByteUtil.byteArrayToHexString(code);
    }

    /**
     * 加密
     *
     * @param inputBytes
     * @param keyBytes
     * @return
     * @throws Exception
     */
    public static String encrypt(byte[] inputBytes, byte[] keyBytes) throws Exception {
        Cipher cipher = Cipher.getInstance(Algorithm_mode); // TripleDES/ECB/NoPadding
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] code = cipher.doFinal(inputBytes);
        return ByteUtil.byteArrayToHexString(code);
    }

    /**
     * 解密
     *
     * @param input
     * @param keyBytes
     * @return
     * @throws Exception
     */
    public static String decrypt(String input, byte[] keyBytes) throws Exception {
        Cipher cipher = Cipher.getInstance(Algorithm_mode);
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] code = cipher.doFinal(ByteUtil.fromHexString(input));
        return new String(code).trim();
    }

    /**
     * 解密
     *
     * @param input
     * @param keyStr
     * @return
     * @throws Exception
     */
    public static String decrypt(String input, String keyStr) throws Exception {
        Cipher cipher = Cipher.getInstance(Algorithm_mode);
        byte[] keyBytes = ByteUtil.fromHexString(keyStr);
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] code = cipher.doFinal(ByteUtil.fromHexString(input));
        return new String(code).trim();
    }

    /**
     * 解密
     *
     * @param inputBytes
     * @param keyBytes
     * @return
     * @throws Exception
     */
    public static String decrypt(byte[] inputBytes, byte[] keyBytes) throws Exception {
        Cipher cipher = Cipher.getInstance(Algorithm_mode);
        SecretKeySpec key = new SecretKeySpec(keyBytes, Algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] code = cipher.doFinal(inputBytes);
        return ByteUtil.byte2Str(code).trim();
    }

    /**
     * 获取随机密钥串
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String getKey() throws NoSuchAlgorithmException {
        SecureRandom sr = new SecureRandom();
        // 为我们选择的DES算法生成一个KeyGenerator对象
        KeyGenerator kg = KeyGenerator.getInstance(Algorithm);
        kg.init(sr);
        // 生成密钥
        SecretKey key = kg.generateKey();
        return ByteUtil.byteArrayToHexString(key.getEncoded());
    }

    /**
     * 根据参数生成KEY
     *
     * @param strKey
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String getKey(String strKey) throws NoSuchAlgorithmException {
        SecureRandom sr = new SecureRandom(strKey.getBytes());
        // 为我们选择的DES算法生成一个KeyGenerator对象
        KeyGenerator kg = KeyGenerator.getInstance(Algorithm);
        kg.init(sr);
        // 生成密钥
        SecretKey key = kg.generateKey();
        return ByteUtil.byteArrayToHexString(key.getEncoded());
    }

    public static void main(String[] args) {
        String input = "sap123456";
        String key = "secureKey";
        try {
            String keyStr = DESedeEncrypt.getKey(key);
            // System.out.println(keyStr);
            // String codeStr = DESedeEncrypt.encrypt(input, keyStr);
            // System.out.println(codeStr);
            String decode = DESedeEncrypt.decrypt("O6XEOFJqZjE5svZfsWjsYg==", keyStr);
            System.out.println(decode);
        } catch (Exception e) {
            // TODO Auto-generated catch block
        }
    }
}
